package com.liuyucheng.idea_springboot.aspect;


import com.liuyucheng.annotation.LogTrack;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.util.Date;

@Aspect
@Component
public class LogTrackAspect  {

    /**
     * 定义一个切点,把添加了LogTrack注解的方法作为一个切点
     */
    @Pointcut(value = "@annotation(com.liuyucheng.annotation.LogTrack)")
    public void access() {}

    /**
     * 前置通知
     * @param point 切点
     */
    @Before("access()")
    public void before(JoinPoint point) {
        //获取注解中设置的属性值
        LogTrack annotation = ((MethodSignature) point.getSignature()).getMethod().getAnnotation(LogTrack.class);
        String value = annotation.value();
        String attr = annotation.attr();
        System.out.println("注解中的value = " + value);
        System.out.println("注解中的attr = " + attr);
        System.out.println("-aop 日志记录启动-" + new Date());
    }


    /**
     * 后置通知,不管方法执行成功还是失败,都会进入这里
     * @param point 切点
     */
    @After("access()")
    public void after(JoinPoint point) {
        System.out.println("-aop 日志记录结束-" + new Date());
    }

    /**
     * 正常执行完成后进入
     * @param point 切点
     */
    @AfterReturning("access()")
    public void afterReturning(JoinPoint point) {
        System.out.println();
    }

    /**
     * 执行出现异常后进入
     * @param point 切点
     */
    @AfterThrowing("access()")
    public void afterThrowing(JoinPoint point) {
        System.out.println();
    }

    /**
     * 环绕通知,是在before前就会触发
     * @param point 切点
     * @return 执行结果
     * @throws Throwable 异常
     */
    @Around("access()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        //执行前
        System.out.println();

        //执行方法
        Object result = point.proceed();

        //执行后
        System.out.println();

        return result;
    }

}